package com.huqing.icu.base.redis.operate;

import com.huqing.icu.exceptions.FastRuntimeException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.jedis.*;
import redis.clients.jedis.params.geo.GeoRadiusParam;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description Redis集群操作类
 * @Author huqing
 * @Date 2025/1/6 10:31
 **/
@Component
public class ClusterRedisOperation implements RedisOperation {

    @Autowired
    private JedisCluster jedis;

    public String set(String key, String value) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.set(key, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.set(key, value);
        }
        return rtnValue;
    }

    public String set(String key, String value, String nxxx, String expx,
                      long time) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.set(key, value, nxxx, expx, time);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.set(key, value, nxxx, expx, time);
        }
        return rtnValue;
    }

    public String get(String key) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.get(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.get(key);
        }
        return rtnValue;
    }

    public Long exists(String... keys) {
        throw new FastRuntimeException("unsupport method");
    }

    public Boolean exists(String key) {
        int last = key.lastIndexOf("_");
        Boolean rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.exists(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.exists(key);
        }
        return rtnValue;
    }

    public Long del(String... keys) {
        int len = keys.length;
        String[] copyKeys = Arrays.copyOf(keys, len);
        String key;
        String hashTag;
        int choose = 0;
        String baseKey = keys[0];
        if (baseKey.lastIndexOf("_") > -1)
            choose = 1;
        for (int i = 0; i < len; i++) {
            key = copyKeys[i];
            if (choose == 1) {
                int last = key.lastIndexOf("_");
                if (last > -1) {
                    hashTag = "{" + key.substring(0, last) + "}";
                    key += hashTag;
                    copyKeys[i] = key;
                }
            } else {
                hashTag = "{HASH}";
                key += hashTag;
                copyKeys[i] = key;
            }
        }

        Long rtnValue = jedis.del(copyKeys);
        return rtnValue;
    }

    public Long del(String key) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.del(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.del(key);
        }
        return rtnValue;
    }

    public String rename(String oldkey, String newkey) {
        int last = oldkey.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + oldkey.substring(0, last) + "}";
            oldkey += hashTag;
            newkey += hashTag;
            rtnValue = jedis.rename(oldkey, newkey);
        } else {
            String hashTag = "{HASH}";
            oldkey += hashTag;
            newkey += hashTag;
            rtnValue = jedis.rename(oldkey, newkey);
        }
        return rtnValue;
    }

    public Long renamenx(String oldkey, String newkey) {
        throw new FastRuntimeException("unsupport method");
    }

    public Long expire(String key, int seconds) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.expire(key, seconds);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.expire(key, seconds);
        }
        return rtnValue;
    }

    public Long expireAt(String key, long unixTime) {
        return null;
    }

    public Long ttl(String key) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.ttl(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.ttl(key);
        }
        return rtnValue;
    }

    public String getSet(String key, String value) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.getSet(key, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.getSet(key, value);
        }
        return rtnValue;
    }

    public List<String> mget(String... keys) {
        int len = keys.length;
        String[] copyKeys = Arrays.copyOf(keys, len);
        String key;
        String hashTag;
        int choose = 0;
        String baseKey = keys[0];
        if (baseKey.lastIndexOf("_") > -1)
            choose = 1;
        for (int i = 0; i < len; i++) {
            key = copyKeys[i];
            if (choose == 1) {
                int last = key.lastIndexOf("_");
                if (last > -1) {
                    hashTag = "{" + key.substring(0, last) + "}";
                    key += hashTag;
                    copyKeys[i] = key;
                }
            } else {
                hashTag = "{HASH}";
                key += hashTag;
                copyKeys[i] = key;
            }

        }
        List<String> rtnValues = jedis.mget(copyKeys);
        return rtnValues;
    }

    public Long setnx(String key, String value) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.setnx(key, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.setnx(key, value);
        }
        return rtnValue;
    }

    public String setex(String key, String value, int seconds) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.setex(key, seconds, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.setex(key, seconds, value);
        }
        return rtnValue;
    }

    public String mset(String... keysvalues) {
        int len = keysvalues.length;
        String key;
        String hashTag;
        for (int i = 0; i < len; i++) {
            if (i % 2 == 0) {
                key = keysvalues[i];
                int last = key.lastIndexOf("_");
                if (last > -1) {
                    hashTag = "{" + key.substring(0, last) + "}";
                    key += hashTag;
                    keysvalues[i] = key;
                }
            }
        }
        String rtnValue = jedis.mset(keysvalues);
        return rtnValue;
    }

    public Long msetnx(String... keysvalues) {
        int len = keysvalues.length;
        String key;
        String hashTag;
        for (int i = 0; i < len; i++) {
            if (i % 2 == 0) {
                key = keysvalues[i];
                int last = key.lastIndexOf("_");
                if (last > -1) {
                    hashTag = "{" + key.substring(0, last) + "}";
                    key += hashTag;
                    keysvalues[i] = key;
                }
            }
        }
        Long rtnValue = jedis.msetnx(keysvalues);
        return rtnValue;
    }

    public Long decrBy(String key, long integer) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.decrBy(key, integer);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.decrBy(key, integer);
        }
        return rtnValue;
    }

    public Long decr(String key) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.decr(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.decr(key);
        }
        return rtnValue;
    }

    public Long incrBy(String key, long integer) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.incrBy(key, integer);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.incrBy(key, integer);
        }
        return rtnValue;
    }

    public Double incrByFloat(String key, double value) {
        int last = key.lastIndexOf("_");
        Double rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.incrByFloat(key, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.incrByFloat(key, value);
        }
        return rtnValue;
    }

    public Long incr(String key) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.incr(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.incr(key);
        }
        return rtnValue;
    }

    public Long append(String key, String value) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.append(key, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.append(key, value);
        }
        return rtnValue;
    }

    public String substr(String key, int start, int end) {
        return getrange(key, start, end);
    }

    public Long hset(String key, String field, String value) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.hset(key, field, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.hset(key, field, value);
        }
        return rtnValue;
    }

    public String hget(String key, String field) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.hget(key, field);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.hget(key, field);
        }
        return rtnValue;
    }

    public Long hsetnx(String key, String field, String value) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.hsetnx(key, field, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.hsetnx(key, field, value);
        }
        return rtnValue;
    }

    public String hmset(String key, Map<String, String> hash) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.hmset(key, hash);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.hmset(key, hash);
        }
        return rtnValue;
    }

    public List<String> hmget(String key, String... fields) {
        int last = key.lastIndexOf("_");
        List<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.hmget(key, fields);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.hmget(key, fields);
        }
        return rtnValues;
    }

    public Long hincrBy(String key, String field, long value) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.hincrBy(key, field, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.hincrBy(key, field, value);
        }
        return rtnValue;
    }

    public Double hincrByFloat(String key, String field, double value) {
        int last = key.lastIndexOf("_");
        Double rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.hincrByFloat(key, field, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.hincrByFloat(key, field, value);
        }
        return rtnValue;
    }

    public Boolean hexists(String key, String field) {
        int last = key.lastIndexOf("_");
        Boolean rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.hexists(key, field);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.hexists(key, field);
        }
        return rtnValue;
    }

    public Long hdel(String key, String... fields) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.hdel(key, fields);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.hdel(key, fields);
        }
        return rtnValue;
    }

    public Long hlen(String key) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.hlen(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.hlen(key);
        }
        return rtnValue;
    }

    public Set<String> hkeys(String key) {
        throw new FastRuntimeException("unsupport method");
    }

    public List<String> hvals(String key) {
        throw new FastRuntimeException("unsupport method");
    }

    public Map<String, String> hgetAll(String key) {
        int last = key.lastIndexOf("_");
        Map<String, String> rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.hgetAll(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.hgetAll(key);
        }
        return rtnValue;
    }

    public Long rpush(String key, String... strings) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.rpush(key, strings);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.rpush(key, strings);
        }
        return rtnValue;
    }

    public Long lpush(String key, String... strings) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.lpush(key, strings);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.lpush(key, strings);
        }
        return rtnValue;
    }

    public Long llen(String key) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.llen(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.llen(key);
        }
        return rtnValue;
    }

    public List<String> lrange(String key, long start, long end) {
        int last = key.lastIndexOf("_");
        List<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.lrange(key, start, end);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.lrange(key, start, end);
        }
        return rtnValues;
    }

    public String ltrim(String key, long start, long end) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.ltrim(key, start, end);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.ltrim(key, start, end);
        }
        return rtnValue;
    }

    public String lindex(String key, long index) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.lindex(key, index);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.lindex(key, index);
        }
        return rtnValue;
    }

    public String lset(String key, long index, String value) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.lset(key, index, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.lset(key, index, value);
        }
        return rtnValue;
    }

    public Long lrem(String key, long count, String value) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.lrem(key, count, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.lrem(key, count, value);
        }
        return rtnValue;
    }

    public String lpop(String key) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.lpop(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.lpop(key);
        }
        return rtnValue;
    }

    public String rpop(String key) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.rpop(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.rpop(key);
        }
        return rtnValue;
    }

    public String rpoplpush(String srckey, String dstkey) {
        int srcKeyLast = srckey.lastIndexOf("_");
        int dstkeyLast = dstkey.lastIndexOf("_");
        String rtnValue;
        if (srcKeyLast > -1 && dstkeyLast > -1) {
            String srcKeyHashTag = srckey.substring(0, srcKeyLast);
            String destKeyHashTag = dstkey.substring(0, dstkeyLast);
            if (!srcKeyHashTag.equals(destKeyHashTag)) {
                srcKeyLast = srckey.lastIndexOf("{HASH}");
                dstkeyLast = dstkey.lastIndexOf("{HASH}");
                if (srcKeyLast == -1 || dstkeyLast == -1)
                    throw new FastRuntimeException("srckey and dstkey must in the same slot");
                else if (srcKeyLast > -1 && dstkeyLast > -1)
                    rtnValue = jedis.rpoplpush(srckey, dstkey);
            } else {
                srckey += "{" + srcKeyHashTag + "}";
                dstkey += "{" + destKeyHashTag + "}";
            }
            rtnValue = jedis.rpoplpush(srckey, dstkey);
            return rtnValue;
        }
        throw new FastRuntimeException("srckey and detkey not in the same slot");
    }

    public Long sadd(String key, String... members) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.sadd(key, members);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.sadd(key, members);
        }
        return rtnValue;
    }

    public Set<String> smembers(String key) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.smembers(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.smembers(key);
        }
        return rtnValue;
    }

    public Long srem(String key, String... members) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.srem(key, members);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.srem(key, members);
        }
        return rtnValue;
    }

    public String spop(String key) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.spop(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.spop(key);
        }
        return rtnValue;
    }

    public Set<String> spop(String key, long count) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.spop(key, count);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.spop(key, count);
        }
        return rtnValues;
    }

    public Long smove(String srckey, String dstkey, String member) {
        int srcKeyLast = srckey.lastIndexOf("_");
        int dstkeyLast = dstkey.lastIndexOf("_");
        Long rtnValue;
        if (srcKeyLast > -1 && dstkeyLast > -1) {
            String srcKeyHashTag = srckey.substring(0, srcKeyLast);
            String destKeyHashTag = dstkey.substring(0, dstkeyLast);
            if (!srcKeyHashTag.equals(destKeyHashTag)) {
                srcKeyLast = srckey.lastIndexOf("{HASH}");
                dstkeyLast = dstkey.lastIndexOf("{HASH}");
                if (srcKeyLast == -1 || dstkeyLast == -1)
                    throw new FastRuntimeException("srckey and dstkey must in the same slot");
                else if (srcKeyLast > -1 && dstkeyLast > -1)
                    rtnValue = jedis.smove(srckey, dstkey, member);
            } else {
                srckey += "{" + srcKeyHashTag + "}";
                dstkey += "{" + destKeyHashTag + "}";
            }
            rtnValue = jedis.smove(srckey, dstkey, member);
            return rtnValue;
        }
        throw new FastRuntimeException("srckey and detkey not in the same slot");
    }

    public Long scard(String key) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.scard(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.scard(key);
        }
        return rtnValue;
    }

    public Boolean sismember(String key, String member) {
        int last = key.lastIndexOf("_");
        Boolean rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.sismember(key, member);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.sismember(key, member);
        }
        return rtnValue;
    }

    public Set<String> sinter(String... keys) {
        int len = keys.length;
        String hashTag;
        String key;
        int choose = 0;
        String baseKey = keys[0];
        if (baseKey.lastIndexOf("_") > -1)
            choose = 1;
        for (int i = 0; i < len; i++) {
            key = keys[i];
            if (choose == 1) {
                int last = key.lastIndexOf("_");
                if (last > -1) {
                    hashTag = "{" + key.substring(0, last) + "}";
                    key += hashTag;
                    keys[i] = key;
                }
            } else {
                hashTag = "{HASH}";
                key += hashTag;
                keys[i] = key;
            }
        }
        Set<String> rtnValues = jedis.sinter(keys);
        return rtnValues;
    }

    public Long sinterstore(String dstkey, String... keys) {
        //TODO
        throw new FastRuntimeException("not support method now");
    }

    public Set<String> sunion(String... keys) {
        //TODO
        throw new FastRuntimeException("not support method now");
    }

    public Long sunionstore(String dstkey, String... keys) {
        //TODO
        throw new FastRuntimeException("not support method now");
    }

    public Set<String> sdiff(String... keys) {
        //TODO
        throw new FastRuntimeException("not support method now");
    }

    public Long sdiffstore(String dstkey, String... keys) {
        //TODO
        throw new FastRuntimeException("not support method now");
    }

    public String srandmember(String key) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.srandmember(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.srandmember(key);
        }
        return rtnValue;
    }

    public List<String> srandmember(String key, int count) {
        int last = key.lastIndexOf("_");
        List<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.srandmember(key, count);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.srandmember(key, count);
        }
        return rtnValues;
    }

    public Long zadd(String key, double score, String member) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zadd(key, score, member);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zadd(key, score, member);
        }
        return rtnValue;
    }

    public Long zadd(String key, Map<String, Double> scoreMembers) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zadd(key, scoreMembers);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zadd(key, scoreMembers);
        }
        return rtnValue;
    }

    public Set<String> zrange(String key, long start, long end) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrange(key, start, end);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrange(key, start, end);
        }
        return rtnValues;
    }

    public Long zrem(String key, String... members) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zrem(key, members);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zrem(key, members);
        }
        return rtnValue;
    }

    public Double zincrby(String key, double score, String member) {
        int last = key.lastIndexOf("_");
        Double rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zincrby(key, score, member);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zincrby(key, score, member);
        }
        return rtnValue;
    }

    public Long zrank(String key, String member) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zrank(key, member);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zrank(key, member);
        }
        return rtnValue;
    }

    public Long zrevrank(String key, String member) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zrevrank(key, member);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zrevrank(key, member);
        }
        return rtnValue;
    }

    public Set<String> zrevrange(String key, long start, long end) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrevrange(key, start, end);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrevrange(key, start, end);
        }
        return rtnValues;
    }

    public Set<Tuple> zrangeWithScores(String key, long start, long end) {
        int last = key.lastIndexOf("_");
        Set<Tuple> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrangeWithScores(key, start, end);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrangeWithScores(key, start, end);
        }
        return rtnValues;
    }

    public Set<Tuple> zrevrangeWithScores(String key, long start, long end) {
        int last = key.lastIndexOf("_");
        Set<Tuple> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrevrangeWithScores(key, start, end);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrevrangeWithScores(key, start, end);
        }
        return rtnValues;
    }

    public Long zcard(String key) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zcard(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zcard(key);
        }
        return rtnValue;
    }

    public Double zscore(String key, String member) {
        int last = key.lastIndexOf("_");
        Double rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zscore(key, member);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zscore(key, member);
        }
        return rtnValue;
    }

    public List<String> sort(String key) {
        int last = key.lastIndexOf("_");
        List<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.sort(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.sort(key);
        }
        return rtnValues;
    }

    public List<String> sort(String key, SortingParams sortingParameters) {
        //TODO
        return null;
    }

    public List<String> blpop(String[] keys, int timeout) {
        //TODO
        throw new FastRuntimeException("not support method now");
    }

    public Long sort(String key, String dstkey) {
        //TODO
        String hashTag = "{" + key + "}";
        key += key + hashTag;
        Long rtnValue = jedis.sort(key, dstkey);
        return rtnValue;
    }

    public Long sort(String key, SortingParams sortingParameters, String dstkey) {
        // TODO Auto-generated method stub
        return null;
    }

    public List<String> brpop(String[] keys, int timeout) {
        //TODO
        throw new FastRuntimeException("not support method now");
    }

    public Long zcount(String key, double min, double max) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zcount(key, min, max);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zcount(key, min, max);
        }
        return rtnValue;
    }

    public Long zcount(String key, String min, String max) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zcount(key, min, max);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zcount(key, min, max);
        }
        return rtnValue;
    }

    public Set<String> zrangeByScore(String key, double min, double max) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrangeByScore(key, min, max);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrangeByScore(key, min, max);
        }
        return rtnValues;
    }

    public Set<String> zrangeByScore(String key, String min, String max) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrangeByScore(key, min, max);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrangeByScore(key, min, max);
        }
        return rtnValues;
    }

    public Set<String> zrangeByScore(String key, double min, double max,
                                     int offset, int count) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrangeByScore(key, min, max, offset, count);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrangeByScore(key, min, max, offset, count);
        }
        return rtnValues;
    }

    public Set<String> zrangeByScore(String key, String min, String max,
                                     int offset, int count) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrangeByScore(key, min, max, offset, count);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrangeByScore(key, min, max, offset, count);
        }
        return rtnValues;
    }

    public Set<Tuple> zrangeByScoreWithScores(String key, double min, double max) {
        throw new FastRuntimeException("unsupport method");
    }

    public Set<Tuple> zrangeByScoreWithScores(String key, String min, String max) {
        throw new FastRuntimeException("unsupport method");
    }

    public Set<Tuple> zrangeByScoreWithScores(String key, double min,
                                              double max, int offset, int count) {
        throw new FastRuntimeException("unsupport method");
    }

    public Set<Tuple> zrangeByScoreWithScores(String key, String min,
                                              String max, int offset, int count) {
        throw new FastRuntimeException("unsupport method");
    }

    public Set<String> zrevrangeByScore(String key, double max, double min) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrevrangeByScore(key, max, min);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrevrangeByScore(key, max, min);
        }
        return rtnValues;
    }

    public Set<String> zrevrangeByScore(String key, String max, String min) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrevrangeByScore(key, max, min);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrevrangeByScore(key, max, min);
        }
        return rtnValues;
    }

    public Set<String> zrevrangeByScore(String key, double max, double min,
                                        int offset, int count) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrevrangeByScore(key, max, min, offset, count);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrevrangeByScore(key, max, min, offset, count);
        }
        return rtnValues;
    }

    public Set<Tuple> zrevrangeByScoreWithScores(String key, double max,
                                                 double min) {
        throw new FastRuntimeException("unsupport method");
    }

    public Set<Tuple> zrevrangeByScoreWithScores(String key, double max,
                                                 double min, int offset, int count) {
        throw new FastRuntimeException("unsupport method");
    }

    public Set<Tuple> zrevrangeByScoreWithScores(String key, String max,
                                                 String min, int offset, int count) {
        throw new FastRuntimeException("unsupport method");
    }

    public Set<String> zrevrangeByScore(String key, String max, String min,
                                        int offset, int count) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrevrangeByScore(key, max, min, offset, count);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrevrangeByScore(key, max, min, offset, count);
        }
        return rtnValues;
    }

    public Set<Tuple> zrevrangeByScoreWithScores(String key, String max,
                                                 String min) {
        throw new FastRuntimeException("unsupport method");
    }

    public Long zremrangeByRank(String key, long start, long end) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zremrangeByRank(key, start, end);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zremrangeByRank(key, start, end);
        }
        return rtnValue;
    }

    public Long zremrangeByScore(String key, double start, double end) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zremrangeByScore(key, start, end);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zremrangeByScore(key, start, end);
        }
        return rtnValue;
    }

    public Long zremrangeByScore(String key, String start, String end) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zremrangeByScore(key, start, end);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zremrangeByScore(key, start, end);
        }
        return rtnValue;
    }

    public Long zunionstore(String dstkey, String... sets) {
        //TODO
        throw new FastRuntimeException("not support method now");
    }

    public Long zinterstore(String dstkey, String... sets) {
        //TODO
        throw new FastRuntimeException("not support method now");
    }

    public Long zlexcount(String key, String min, String max) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zlexcount(key, min, max);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zlexcount(key, min, max);
        }
        return rtnValue;
    }

    public Set<String> zrangeByLex(String key, String min, String max) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrangeByLex(key, min, max);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrangeByLex(key, min, max);
        }
        return rtnValues;
    }

    public Set<String> zrangeByLex(String key, String min, String max,
                                   int offset, int count) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrangeByLex(key, min, max, offset, count);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrangeByLex(key, min, max, offset, count);
        }
        return rtnValues;
    }

    public Set<String> zrevrangeByLex(String key, String max, String min) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrevrangeByLex(key, max, min);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrevrangeByLex(key, max, min);
        }
        return rtnValues;
    }

    public Set<String> zrevrangeByLex(String key, String max, String min,
                                      int offset, int count) {
        int last = key.lastIndexOf("_");
        Set<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.zrevrangeByLex(key, max, min, offset, count);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.zrevrangeByLex(key, max, min, offset, count);
        }
        return rtnValues;
    }

    public Long zremrangeByLex(String key, String min, String max) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.zremrangeByLex(key, min, max);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.zremrangeByLex(key, min, max);
        }
        return rtnValue;
    }

    public Long strlen(String key) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.strlen(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.strlen(key);
        }
        return rtnValue;
    }

    public Long lpushx(String key, String... string) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.lpushx(key, string);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.lpushx(key, string);
        }
        return rtnValue;
    }

    public Long persist(String key) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.persist(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.persist(key);
        }
        return rtnValue;
    }

    public Long rpushx(String key, String... string) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.rpushx(key, string);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.rpushx(key, string);
        }
        return rtnValue;
    }

    public Long linsert(String key, LIST_POSITION where, String pivot,
                        String value) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.linsert(key, where, pivot, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.linsert(key, where, pivot, value);
        }
        return rtnValue;
    }

    public String brpoplpush(String source, String destination, int timeout) {
        int srcKeyLast = source.lastIndexOf("_");
        int dstkeyLast = destination.lastIndexOf("_");
        String rtnValue;
        if (srcKeyLast > -1 && dstkeyLast > -1) {
            String srcKeyHashTag = source.substring(0, srcKeyLast);
            String destKeyHashTag = destination.substring(0, dstkeyLast);
            if (!srcKeyHashTag.equals(destKeyHashTag)) {
                srcKeyLast = source.lastIndexOf("{HASH}");
                dstkeyLast = destination.lastIndexOf("{HASH}");
                if (srcKeyLast == -1 || dstkeyLast == -1)
                    throw new FastRuntimeException("source and destination must in the same slot");
                else if (srcKeyLast > -1 && dstkeyLast > -1)
                    rtnValue = jedis.rpoplpush(source, destination);
            } else {
                source += "{" + srcKeyHashTag + "}";
                destination += "{" + destKeyHashTag + "}";
            }
            rtnValue = jedis.rpoplpush(source, destination);
            return rtnValue;
        }
        throw new FastRuntimeException("source and destination not in the same slot");
    }

    public Boolean setbit(String key, long offset, boolean value) {
        int last = key.lastIndexOf("_");
        Boolean rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.setbit(key, offset, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.setbit(key, offset, value);
        }
        return rtnValue;
    }

    public Boolean setbit(String key, long offset, String value) {
        int last = key.lastIndexOf("_");
        Boolean rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.setbit(key, offset, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.setbit(key, offset, value);
        }
        return rtnValue;
    }

    public Boolean getbit(String key, long offset) {
        int last = key.lastIndexOf("_");
        Boolean rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.getbit(key, offset);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.getbit(key, offset);
        }
        return rtnValue;
    }

    public Long setrange(String key, long offset, String value) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.setrange(key, offset, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.setrange(key, offset, value);
        }
        return rtnValue;
    }

    public String getrange(String key, long startOffset, long endOffset) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.getrange(key, startOffset, endOffset);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.getrange(key, startOffset, endOffset);
        }
        return rtnValue;
    }

    public Long bitcount(String key) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.bitcount(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.bitcount(key);
        }
        return rtnValue;
    }

    public Long bitcount(String key, long start, long end) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.bitcount(key, start, end);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.bitcount(key, start, end);
        }
        return rtnValue;
    }

    public Long bitop(BitOP op, String destKey, String... srcKeys) {
        //TODO
        throw new FastRuntimeException("not support method now");
    }

    public List<Map<String, String>> sentinelMasters() {
        throw new FastRuntimeException("waiting for support method");
    }

    public List<String> sentinelGetMasterAddrByName(String masterName) {
        throw new FastRuntimeException("waiting for support method");
    }

    public Long sentinelReset(String pattern) {
        throw new FastRuntimeException("waiting for support method");
    }

    public List<Map<String, String>> sentinelSlaves(String masterName) {
        throw new FastRuntimeException("waiting for support method");
    }

    public String sentinelFailover(String masterName) {
        throw new FastRuntimeException("waiting for support method");
    }

    public String sentinelMonitor(String masterName, String ip, int port,
                                  int quorum) {
        throw new FastRuntimeException("waiting for support method");
    }

    public String sentinelRemove(String masterName) {
        throw new FastRuntimeException("waiting for support method");
    }

    public String sentinelSet(String masterName,
                              Map<String, String> parameterMap) {
        throw new FastRuntimeException("waiting for support method");
    }

    public Long pexpire(String key, long milliseconds) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.pexpire(key, milliseconds);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.pexpire(key, milliseconds);
        }
        return rtnValue;
    }

    public Long pexpireAt(String key, long millisecondsTimestamp) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.pexpireAt(key, millisecondsTimestamp);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.pexpireAt(key, millisecondsTimestamp);
        }
        return rtnValue;
    }

    public Long pttl(String key) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.pttl(key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.pttl(key);
        }
        return rtnValue;
    }

    public String psetex(String key, long milliseconds, String value) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.psetex(key, milliseconds, value);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.psetex(key, milliseconds, value);
        }
        return rtnValue;
    }

    public String set(String key, String value, String nxxx) {
        throw new FastRuntimeException("unsupport method");
    }

    public String set(String key, String value, String nxxx, String expx,
                      int time) {
        int last = key.lastIndexOf("_");
        String rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.set(key, value, nxxx, expx, time);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.set(key, value, nxxx, expx, time);
        }
        return rtnValue;
    }

    public List<String> blpop(String key, int timeout) {
        int last = key.lastIndexOf("_");
        List<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.blpop(timeout, key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.blpop(timeout, key);
        }
        return rtnValues;
    }

    public List<String> brpop(String key, int timeout) {
        int last = key.lastIndexOf("_");
        List<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.brpop(timeout, key);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.brpop(timeout, key);
        }
        return rtnValues;
    }

    public Long geoadd(String key, double longitude, double latitude,
                       String member) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.geoadd(key, longitude, latitude, member);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.geoadd(key, longitude, latitude, member);
        }
        return rtnValue;
    }

    public Long geoadd(String key, Map<String, GeoCoordinate> memberCoordinateMap) {
        int last = key.lastIndexOf("_");
        Long rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.geoadd(key, memberCoordinateMap);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.geoadd(key, memberCoordinateMap);
        }
        return rtnValue;
    }

    public Double geodist(String key, String member1, String member2) {
        int last = key.lastIndexOf("_");
        Double rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.geodist(key, member1, member2);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.geodist(key, member1, member2);
        }
        return rtnValue;
    }

    public Double geodist(String key, String member1, String member2,
                          GeoUnit unit) {
        int last = key.lastIndexOf("_");
        Double rtnValue;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValue = jedis.geodist(key, member1, member2);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValue = jedis.geodist(key, member1, member2);
        }
        return rtnValue;
    }

    public List<String> geohash(String key, String... members) {
        int last = key.lastIndexOf("_");
        List<String> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.geohash(key, members);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.geohash(key, members);
        }
        return rtnValues;
    }

    public List<GeoCoordinate> geopos(String key, String... members) {
        int last = key.lastIndexOf("_");
        List<GeoCoordinate> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.geopos(key, members);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.geopos(key, members);
        }
        return rtnValues;
    }

    public List<GeoRadiusResponse> georadius(String key, double longitude,
                                             double latitude, double radius, GeoUnit unit) {
        int last = key.lastIndexOf("_");
        List<GeoRadiusResponse> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.georadius(key, longitude, latitude, radius, unit);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.georadius(key, longitude, latitude, radius, unit);
        }
        return rtnValues;
    }

    public List<GeoRadiusResponse> georadius(String key, double longitude,
                                             double latitude, double radius, GeoUnit unit, GeoRadiusParam param) {
        int last = key.lastIndexOf("_");
        List<GeoRadiusResponse> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.georadius(key, longitude, latitude, radius, unit, param);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.georadius(key, longitude, latitude, radius, unit, param);
        }
        return rtnValues;
    }

    public List<GeoRadiusResponse> georadiusByMember(String key, String member,
                                                     double radius, GeoUnit unit) {
        int last = key.lastIndexOf("_");
        List<GeoRadiusResponse> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.georadiusByMember(key, member, radius, unit);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.georadiusByMember(key, member, radius, unit);
        }
        return rtnValues;
    }

    public List<GeoRadiusResponse> georadiusByMember(String key, String member,
                                                     double radius, GeoUnit unit, GeoRadiusParam param) {
        int last = key.lastIndexOf("_");
        List<GeoRadiusResponse> rtnValues;
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
            rtnValues = jedis.georadiusByMember(key, member, radius, unit, param);
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
            rtnValues = jedis.georadiusByMember(key, member, radius, unit, param);
        }
        return rtnValues;
    }

    @Override
    public Object eval(String script, List<String> keys, List<String> args) {
        List<String> newKeys = keys.stream().map(i -> {
            int last = i.lastIndexOf("_");
            if (last > -1) {
                String hashTag = "{" + i.substring(0, last) + "}";
                i += hashTag;
            } else {
                String hashTag = "{HASH}";
                i += hashTag;
            }
            return i;
        }).collect(Collectors.toList());
        return jedis.eval(script, newKeys, args);
    }

    public List<String> blpop(String... args) {
        throw new FastRuntimeException("unsupport method");
    }

    public List<String> brpop(String... args) {
        throw new FastRuntimeException("unsupport method");
    }


    private static final String LUA_DEL_VALUE_IN_LIST = "local length=redis.call(\"llen\",KEYS[1])\n"
            + "if(length>0)then\n"
            + "  local values=redis.call(\"Lrange\",KEYS[1],0,length-1)\n"
            + "  local index=-1\n"
            + "  for i = 1, length,1 do\n"
            + "    if(string.find(values[i],ARGV[1]))\n"
            + "\tthen\n"
            + "\t  index=i\n"
            + "      redis.call(\"LREM\",KEYS[1],0,values[i])\n"
            + "      break\n"
            + "\t  end\n"
            + "    end\n"
            + "    return 1\n"
            + "else\n"
            + "    return 0 \n"
            + "end";

    public Long delValueInList(String key, String param) {
        key = getHashTagKey(key);
        Object rs = jedis.eval(LUA_DEL_VALUE_IN_LIST, Arrays.asList(key), Arrays.asList(param));
        return Long.valueOf(rs.toString());

    }


    private static final String LUA_LPOP_BATCH = "local count = 0\n"
            + "local totalCount = tonumber(ARGV[1])\n"
            + "while count < totalCount do\n"
            + "  redis.call(\"LPOP\",KEYS[1])\n"
            + "  count = count + 1\n"
            + "end\n"
            + "return count";

    @Override
    public Long lpopBatch(String key, String param) {
        key = getHashTagKey(key);
        Object rs = jedis.eval(LUA_LPOP_BATCH, Arrays.asList(key), Arrays.asList(param));
        return Long.valueOf(rs.toString());
    }

    private String getHashTagKey(String key) {
        int last = key.lastIndexOf("_");
        if (last > -1) {
            String hashTag = "{" + key.substring(0, last) + "}";
            key += hashTag;
        } else {
            String hashTag = "{HASH}";
            key += hashTag;
        }

        return key;
    }
}

